package com.nineclock.system.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.aliyun.oss.OSS;
import com.aliyun.oss.model.PutObjectResult;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.nineclock.common.constant.NcConstant;
import com.nineclock.common.constant.SMSConstant;
import com.nineclock.common.enums.ResponseEnum;
import com.nineclock.common.exception.NcException;
import com.nineclock.common.oss.OssProperties;
import com.nineclock.common.threadlocal.CurrentUserHolder;
import com.nineclock.common.utils.BeanHelper;
import com.nineclock.message.pojo.NcMessage;
import com.nineclock.sign.pojo.SignPicture;
import com.nineclock.system.dto.*;
import com.nineclock.system.mapper.*;
import com.nineclock.system.pojo.*;
import com.nineclock.system.service.SysCompanyService;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.json.AutoConfigureJsonTesters;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author 黑马程序员
 * @Company http://www.ithiema.com
 * @Version 1.0
 */
@Service
@Slf4j
public class SysCompanyServiceImpl implements SysCompanyService {

    @Autowired
    SysCompanyMapper companyMapper;

    @Autowired
    SysCompanyUserMapper companyUserMapper;

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    SysRoleMapper roleMapper;

    @Autowired
    SysCompanyUserRoleMapper companyUserRoleMapper;

    @Autowired
    SysUserMapper userMapper;


    @Autowired
    RocketMQTemplate rocketMQTemplate;

    /**
     * 根据系统用户id查询 企业列表
     * @param userId
     * @return
     */
    @Override
    public List<SysCompanyDTO> queryCompanyListByUserId(Long userId) {
        if(userId == null){
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }

        //根据 系统用户id 查询 企业员工列表
        LambdaQueryWrapper<SysCompanyUser> companyUserQw = new LambdaQueryWrapper<>();

        companyUserQw.eq(SysCompanyUser::getUserId, userId);
        //获取企业员工列表
        List<SysCompanyUser> companyUserList = companyUserMapper.selectList(companyUserQw);
        if(CollectionUtil.isEmpty(companyUserList)){
            throw new NcException(ResponseEnum.USER_NOT_JOIN_COMPANY);
        }
        //从企业员工列表中获取 企业id
        //map 可以把集合转换为一个新的集合
        //collect(Collectors.toSet()) 指定要转换成什么集合类型
        Set<Long> companyIds = companyUserList.stream().map(companyUser -> {
            return companyUser.getCompanyId();
        }).collect(Collectors.toSet());

        //再根据企业id获取 企业列表信息
        LambdaQueryWrapper<SysCompany> companyQw = new LambdaQueryWrapper<>();
        companyQw.in(SysCompany::getId, companyIds);

        List<SysCompany> companyList = companyMapper.selectList(companyQw);


        //转换为DTO
        List<SysCompanyDTO> companyDTOList = BeanHelper.copyWithCollection(companyList, SysCompanyDTO.class);

        return companyDTOList;
    }

    @Override
    public SysCompanyDTO queryCompanyInfo() {
        //从线程中获取企业id
        Long companyId = CurrentUserHolder.get().getCompanyId();
        //获取企业信息
        SysCompany company = companyMapper.selectById(companyId);
        if(company == null){
            throw new NcException(ResponseEnum.COMPANY_NOT_FOUND);
        }

        SysCompanyDTO companyDTO = BeanHelper.copyProperties(company, SysCompanyDTO.class);
        return companyDTO;
    }
    @Autowired
    OSS oss;

    @Autowired
    OssProperties ossProperties;


    @Override
    public String uploadCompanyLogo(MultipartFile file) throws IOException {
        if(file == null){
            throw new NcException(ResponseEnum.FILE_UPLOAD_ERROR);
        }

//        String contentType = file.getContentType();
//        if(! NcConstant.ALLOWED_IMG_TYPES.contains(contentType)){
//            throw new NcException(ResponseEnum.INVALID_FILE_TYPE);
//        }

        if(file.getSize() > NcConstant.maxFileSize){
            throw new NcException(ResponseEnum.FILE_SIZE_EXCEED_MAX_LIMIT);
        }

        //file.getOriginalFilename() 获取原始文件名(包含后缀)
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmssSSS");
        String fileName = dateFormat.format(new Date()) + file.getOriginalFilename();
        //图片上传( 存储空间名称 ， 文件名， 文件流对象 )

        PutObjectResult putObjectResult = oss.putObject(ossProperties.getBucketName(), fileName, file.getInputStream());
        log.info("上传图片的结果："+putObjectResult.getResponse());
        //host : https://%s.oss-cn-beijing.aliyuncs.com/
        // bucketName: nineclock-itheima
        //https://nineclock-itheima.oss-cn-beijing.aliyuncs.com/


        String filePath = String.format(ossProperties.getHost() , ossProperties.getBucketName())  + fileName;
        log.info("企业logo路径："+filePath);


        return filePath;
    }

    @Override
    public void updateCompanyInfo(SysCompanyDTO sysCompanyDTO) {
        if(sysCompanyDTO == null){
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }
        Long companyId = CurrentUserHolder.get().getCompanyId();
        //根据企业id查询企业信息
        SysCompany company = companyMapper.selectById(companyId);
        if(company == null){
            throw new NcException(ResponseEnum.COMPANY_NOT_FOUND);
        }
        //再更新数据库
        company.setLogo(sysCompanyDTO.getLogo());
        company.setName(sysCompanyDTO.getName());

        companyMapper.updateById(company);
    }

    @Override
    public SysCompanyUserDTO queryCompanyAdmin() {
        Long companyId = CurrentUserHolder.get().getCompanyId();
        SysCompanyUser companyUser = companyMapper.getCurrentAdmin(companyId);
        if(companyUser == null){
            throw new NcException(ResponseEnum.COMPANY_ADMIN_NOT_EXISTS);
        }
        SysCompanyUserDTO companyUserDTO = BeanHelper.copyProperties(companyUser, SysCompanyUserDTO.class);
        return companyUserDTO;
    }

    /**
     * 1. 健壮性判断
     * 2. 新管理员 是否存在
     * 3. 校验验证码是否正确
     * 4. 删除原管理员与角色的关系， 添加新管理员的关系
     * @param sysChangeMainManagerDTO
     */
    @Override
    public void changeSysAdmin(SysChangeMainManagerDTO sysChangeMainManagerDTO) {

        Long companyId = CurrentUserHolder.get().getCompanyId();

        if(sysChangeMainManagerDTO == null){
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }
        //验证新管理员 是否存在
        LambdaQueryWrapper<SysCompanyUser> companyUserQw = new LambdaQueryWrapper<>();
        companyUserQw.eq(SysCompanyUser::getCompanyId, companyId);
        companyUserQw.eq(SysCompanyUser::getEnable, 1);
        companyUserQw.eq(SysCompanyUser::getId, sysChangeMainManagerDTO.getUserId() );

        SysCompanyUser companyUser = companyUserMapper.selectOne(companyUserQw);
        if(companyUser == null){
            throw new NcException(ResponseEnum.USER_NOT_FOUND);
        }

        //验证码是否正确
        String userCode = sysChangeMainManagerDTO.getCode();

        //获取redis中的验证码
        Object realCode = redisTemplate.boundValueOps(SMSConstant.SMS_TYPE_CHANGE_MANAGER + companyUser.getMobile()).get();
        if(realCode == null || !realCode.equals(userCode)){
            throw new NcException(ResponseEnum.INVALID_VERIFY_CODE);
        }

        //4. 删除原管理员与角色的关系， 添加新管理员的关系
        //获取主管理员 角色 id

        LambdaQueryWrapper<SysRole> roleQw = new LambdaQueryWrapper<>();
        roleQw.eq(SysRole::getRoleName, "ROLE_ADMIN_SYS");
        roleQw.eq(SysRole::getCompanyId, companyId);
        SysRole role = roleMapper.selectOne(roleQw);


        //删除原管理员关系
        LambdaQueryWrapper<SysCompanyUserRole> companyUserRoleQw = new LambdaQueryWrapper<>();
        companyUserRoleQw.eq(SysCompanyUserRole::getCompanyId, companyId);
        companyUserRoleQw.eq(SysCompanyUserRole::getCompanyUserId, CurrentUserHolder.get().getCompanyUserId());
        companyUserRoleQw.eq(SysCompanyUserRole::getRoleId, role.getId());
        companyUserRoleMapper.delete(companyUserRoleQw);

        //添加信息的关系
        SysCompanyUserRole companyUserRole = new SysCompanyUserRole();
        companyUserRole.setCompanyId(companyId);
        companyUserRole.setRoleId(role.getId());
        companyUserRole.setCompanyUserId(sysChangeMainManagerDTO.getUserId());

        companyUserRoleMapper.insert(companyUserRole);
    }

    @Override
    public List<SysCompanyDTO> queryCompanyByName(String keyword) {
        if(keyword == null){
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }

        LambdaQueryWrapper<SysCompany> companyQw = new LambdaQueryWrapper<>();
        companyQw.like(SysCompany::getName, keyword); //根据关键词模糊查询
        companyQw.eq(SysCompany::getAuditStatus, 1); //获取有效企业信息

        List<SysCompany> companyList = companyMapper.selectList(companyQw);
        if(CollectionUtil.isNotEmpty(companyList)){
            List<SysCompanyDTO> companyDTOList = BeanHelper.copyWithCollection(companyList, SysCompanyDTO.class);
            return companyDTOList;
        }
        return new ArrayList<>();
    }

    @Override
    public void applyJoinCompany(SysApplyJoinCompanyUserDTO applyJoinCompanyUserDTO) {
        if(applyJoinCompanyUserDTO == null || applyJoinCompanyUserDTO.getUserId() == null || applyJoinCompanyUserDTO.getCompanyId() == null){
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }

        //1. 完善用户信息
        SysUser user = userMapper.selectById(applyJoinCompanyUserDTO.getUserId());
        user.setUsername(applyJoinCompanyUserDTO.getUserName());
        user.setEmail(applyJoinCompanyUserDTO.getEmail());
        user.setLastLoginCompanyId(applyJoinCompanyUserDTO.getCompanyId());

        userMapper.updateById(user);

        //2. 加入企业(把信息添加员工表)
        SysCompanyUser companyUser = new SysCompanyUser();
        companyUser.setUserId(applyJoinCompanyUserDTO.getUserId()); //用户id
        companyUser.setCompanyId(applyJoinCompanyUserDTO.getCompanyId()); //企业id
        companyUser.setCompanyName(applyJoinCompanyUserDTO.getCompanyName()); //企业名称
        companyUser.setPost(applyJoinCompanyUserDTO.getPost());//职位
        companyUser.setEmail(applyJoinCompanyUserDTO.getEmail());//邮箱
        companyUser.setTimeEntry(new Date()); // 加入时间
        companyUser.setRemark(applyJoinCompanyUserDTO.getApplyReason()); //申请原因
        companyUser.setEnable((short)0);//有效标记
        companyUser.setCreateTime(new Date()); //创建时间
        companyUser.setMobile(applyJoinCompanyUserDTO.getMobile());// 手机号
        companyUser.setUserName(applyJoinCompanyUserDTO.getUserName());
        companyUser.setImageUrl(applyJoinCompanyUserDTO.getImageUrl());

        companyUserMapper.insert(companyUser);

        //获取系统主管理员
        SysCompanyUser currentAdmin = companyMapper.getCurrentAdmin(applyJoinCompanyUserDTO.getCompanyId());

        //加入企业完成后， 推送消息给企业管理员
        NcMessage message = new NcMessage();
        message.setApplyUserId(companyUser.getId()); //申请人id
        message.setApplyUsername(companyUser.getUserName()); //申请人姓名
        message.setApproveUserId(currentAdmin.getUserId()); //审批人id
        message.setApproveUsername(currentAdmin.getUserName()); //审批人姓名
        message.setTargets(Arrays.asList(currentAdmin.getMobile())); // 消息推送的目标(审批人的手机号)
        message.setContent(companyUser.getUserName() +"申请加入企业");


        rocketMQTemplate.convertAndSend("messagePushTopic", message);
    }

    @Override
    public void allowedJoinCompany(SysAllowedJoinCompanyUserDTO sysAllowedJoinCompanyUserDTO) {
        if(sysAllowedJoinCompanyUserDTO == null){
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }
        //更新数据库信息
        LambdaQueryWrapper<SysCompanyUser> companyUserQw = new LambdaQueryWrapper<>();
        companyUserQw.eq(SysCompanyUser::getCompanyId, CurrentUserHolder.get().getCompanyId());
        companyUserQw.eq(SysCompanyUser::getId, sysAllowedJoinCompanyUserDTO.getApplyUserId());

        SysCompanyUser companyUser = companyUserMapper.selectOne(companyUserQw);

        companyUser.setRemark(sysAllowedJoinCompanyUserDTO.getRemark());
        companyUser.setEnable(sysAllowedJoinCompanyUserDTO.getApproved() ? (short)1 : (short)0);

        companyUserMapper.updateById(companyUser);

        if(sysAllowedJoinCompanyUserDTO.getApproved()){
            //更新mongodb
            rocketMQTemplate.convertAndSend("allowedJoinCompanyTopic" , sysAllowedJoinCompanyUserDTO.getNotifyMsgId());

            //推送消息给用户
            NcMessage message = new NcMessage();
            message.setApplyUserId(sysAllowedJoinCompanyUserDTO.getApplyUserId());
            message.setApplyUsername(companyUser.getUserName());
            message.setContent(companyUser.getUserName() + ",您的申请已通过!!");
            message.setApproveUserId(CurrentUserHolder.get().getId());
            message.setApplyUsername(CurrentUserHolder.get().getUsername());

            message.setTargets(Arrays.asList(companyUser.getMobile()));

            rocketMQTemplate.convertAndSend("messagePushTopic", message);
        }




    }
}
